#include "service/auth/auth_service.h"
#include "database/mysql_pool.h"
#include "cache/redis_client.h"
#include <iostream>
#include <fstream>
#include <nlohmann/json.hpp>
#include <csignal>
#include <thread>
#include <chrono>
#include <vector>

// 全局认证服务指针，用于信号处理
std::shared_ptr<service::auth::AuthService> g_authService;

// 信号处理函数
void signalHandler(int signum) {
    std::cout << "接收到信号: " << signum << std::endl;
    if (g_authService) {
        std::cout << "正在停止认证服务..." << std::endl;
        g_authService->stop();
    }
    exit(signum);
}

// 加载配置文件
bool loadConfig(const std::string& configFile, nlohmann::json& config) {
    std::ifstream file(configFile);
    if (!file.is_open()) {
        std::cerr << "尝试打开配置文件失败: " << configFile << std::endl;
        return false;
    }

    try {
        file >> config;
        return true;
    } catch (const nlohmann::json::parse_error& e) {
        std::cerr << "解析配置文件失败: " << e.what() << std::endl;
        return false;
    }
}

// 查找并加载配置文件
bool findAndLoadConfig(const std::string& configFileName, nlohmann::json& config) {
    // 尝试多个可能的位置
    std::vector<std::string> possiblePaths = {
        configFileName,                    // 直接使用提供的路径
        "config/" + configFileName,        // 相对于当前目录的config子目录
        "../config/" + configFileName,     // 上级目录的config
        "../../config/" + configFileName,  // 上上级目录的config
        "../../../config/" + configFileName // 上上上级目录的config
    };
    
    for (const auto& path : possiblePaths) {
        std::cout << "尝试加载配置文件: " << path << std::endl;
        if (loadConfig(path, config)) {
            std::cout << "成功加载配置文件: " << path << std::endl;
            return true;
        }
    }
    
    std::cerr << "无法在任何位置找到配置文件: " << configFileName << std::endl;
    return false;
}

int main(int argc, char* argv[]) {
    // 注册信号处理函数
    signal(SIGINT, signalHandler);
    signal(SIGTERM, signalHandler);

    // 默认配置文件名
    std::string configFile = "auth_service.json";

    // 如果命令行指定了配置文件，则使用指定的配置文件
    if (argc > 1) {
        configFile = argv[1];
    }

    // 加载配置
    nlohmann::json config;
    if (!findAndLoadConfig(configFile, config)) {
        return 1;
    }

    // 获取配置项
    int port = config.value("port", 8001);
    
    // 数据库配置
    std::string dbHost = config["database"].value("host", "localhost");
    int dbPort = config["database"].value("port", 3306);
    std::string dbUser = config["database"].value("user", "root");
    std::string dbPassword = config["database"].value("password", "");
    std::string dbName = config["database"].value("database", "blog_system");
    int dbPoolSize = config["database"].value("pool_size", 10);

    // Redis配置
    std::string redisHost = config["redis"].value("host", "localhost");
    int redisPort = config["redis"].value("port", 6379);
    std::string redisPassword = config["redis"].value("password", "");
    int redisDb = config["redis"].value("db", 0);

    try {
        // 创建数据库连接池
        auto dbPool = database::MySQLPool::create(
            dbHost, dbUser, dbPassword, dbName, dbPort, dbPoolSize);

        // 创建Redis客户端
        cache::RedisConfig redisConfig;
        redisConfig.host = redisHost;
        redisConfig.port = redisPort;
        redisConfig.password = redisPassword;
        redisConfig.db = redisDb;
        auto redisPool = cache::RedisPool::create(redisConfig);
        auto redisClient = std::make_shared<cache::RedisClient>(redisPool);

        // 创建认证服务
        g_authService = service::auth::AuthService::create(dbPool, redisClient);

        // 启动服务
        std::cout << "认证服务正在启动，监听端口: " << port << std::endl;
        if (!g_authService->start(port)) {
            std::cerr << "启动认证服务失败" << std::endl;
            return 1;
        }

        // 主线程保持运行
        while (true) {
            std::this_thread::sleep_for(std::chrono::seconds(1));
        }
    } catch (const std::exception& e) {
        std::cerr << "发生异常: " << e.what() << std::endl;
        return 1;
    }

    return 0;
} 